﻿using Gdmec.Config;
using System.Collections;
using System.IO;
using UnityEngine;

namespace Gdmec.Load
{
    //加载器工人
    public class LoadWorker
    {
        public LoadTask task;
        public LoadParam param;
        public Coroutine coroutine;
        public LoadWorkerState state = LoadWorkerState.Node;
        public Object obj;
        public string read_path = string.Empty;
        public bool IsFinish { get { return state == LoadWorkerState.Loaded; } }

        public void Init()
        {
            state = LoadWorkerState.Init;
        }

        public void UnInit()
        {
            task = null;
            param = null;
            coroutine = null;
            obj = null;
        }

        public IEnumerator Load(Loader loader, LoadWorker worker)
        {
            worker.state = LoadWorkerState.Loading;
            //缓存加载
            if (worker.state == LoadWorkerState.Loading)
            {
                worker.obj = loader.GetCache(worker.param.path);
                if (worker.obj != null)
                {
                    worker.state = LoadWorkerState.Loaded;
                    yield return null;
                    loader.WorkerFinish(worker);
                }
            }
            if (worker.state == LoadWorkerState.Loaded) yield break;
            //AB加载
            if (worker.state == LoadWorkerState.Loading)
            {
                var path = GameConfig.ToProjectPath(GameConfig.AssetBundleFilePath) + "/" + worker.param.path;
                if (File.Exists(path))
                {
                    var abRequest = AssetBundle.LoadFromFileAsync(path);
                    while ((!abRequest.isDone))
                    {
                        yield return null;
                    }
                    worker.obj = abRequest.assetBundle;
                    if (worker.obj != null)
                    {
                        worker.state = LoadWorkerState.Loaded;
                        loader.Cache.Set(worker.param.path, worker.obj);
                        yield return null;
                        loader.WorkerFinish(worker);
                    }
                }
            }
            if (worker.state == LoadWorkerState.Loaded) yield break;
            //热更加载
            if (worker.state == LoadWorkerState.Loading)
            {

                var path = GameConfig.ToHotFixPath(worker.param.path);
                if (File.Exists(path))
                {
                    var abRequest = AssetBundle.LoadFromFileAsync(path);
                    while (!abRequest.isDone)
                    {
                        yield return null;
                    }
                    worker.obj = abRequest.assetBundle;
                    if (worker.obj != null)
                    {
                        worker.state = LoadWorkerState.Loaded;
                        loader.Cache.Set(worker.param.path, worker.obj);
                        yield return null;
                        loader.WorkerFinish(worker);
                    }
                }
            }
            if (worker.state == LoadWorkerState.Loaded) yield break;
            //流加载
            if (worker.state == LoadWorkerState.Loading)
            {
                var path = GameConfig.ToStreamingAssetPath(worker.param.path);
                var abRequest = AssetBundle.LoadFromFileAsync(path);
                while (!abRequest.isDone)
                {
                    yield return null;
                }
                worker.obj = abRequest.assetBundle;
                if (worker.obj != null)
                {
                    worker.state = LoadWorkerState.Loaded;
                    loader.Cache.Set(worker.param.path, worker.obj);
                    yield return null;
                    loader.WorkerFinish(worker);
                }
            }
            if (worker.state == LoadWorkerState.Loaded) yield break;
        }
    }

    public enum LoadWorkerState
    {
        Node = 0,
        Init = 1,
        Loading = 2,
        Loaded = 3,
        Error = 4,
    }
}
